import { Modal, Select, Tree, Result, Spin, Checkbox, Button, message, DatePicker } from 'antd'
import { project } from '../../Data'
import { Http } from '../../Api'
import Draggable from 'react-draggable'
import { useRef, useState, useEffect } from 'react'
import { useBoolean, useRequest } from 'ahooks'
import { useLatest } from '@ant-design/pro-components'
import dayjs from 'dayjs'

const { imageUrl } = project[window.location.hostname]
const { Autodesk, THREE } = window
const { Group } = Checkbox
const { RangePicker } = DatePicker

const ModalSelectColor = new THREE.Vector4(255 / 255, 0 / 255, 0 / 255, 1)
const GetNewArr = (a, b) => [...a, ...b].filter(item => !(a.includes(item) && b.includes(item)))

const ApiUrlList = {
    planAdd: 'getGetBIMModlesInfoExternalIdPlan',
    planDel: 'getGetBIMPlanModlesInfoExternalId',
    finishAdd: 'getGetBIMModlesInfoExternalIdFinish',
    finishDel: 'getGetBIMFinishModlesInfoExternalId',
}

const ButtonText = {
    planAdd: '添加计划进度',
    planDel: '删除计划进度',
    finishAdd: '添加实际进度',
    finishDel: '删除实际进度',
}

export const ForgeBox = ({ type, Off, data }) => {
    return (
        <Modal
            className="ModalBox"
            open={true}
            footer={null}
            maskClosable={false}
            onCancel={Off}
            destroyOnClose
            title={data.tableName || '添加实际进度'}
            centered
            width={'90vw'}
        >
            <ForgeProgress type={type} BIMPlanUuid={data.uuid} organizationUuid={data.organizationUuid} />
        </Modal>
    )
}

/**
 *
 * @param runAsync
 * @returns getFiles            获取模型列表
 * @returns getBIMDetails       获取已有进度
 * @returns OptionalModalId     获取可选组件
 * @returns OptionalModalTree   获取可选树
 * @returns posBIMDetails       添加模型进度数据
 * @returns delBimDetails       删除模型进度数据
 *
 * @param 变量
 * @returns FilesStatus         模型可选状态
 * @returns FilesList           模型列表
 * @returns FilesUrl            已选模型路径
 * @returns TreeData            树数据
 * @returns CheckName           选中树形的构建组名称
 * @returns PlainOptions        多选框全选属性
 * @returns CheckStatus         多选框全选状态
 * @returns CheckSelect         多选框选中结果集
 * @returns CheckAll            多选框全选状态
 * @returns CheckAllIn          多选框全选状态
 * @returns ModalTime           模型实际进度时间
 * @returns ModalActiveData     删除记录的对比数据
 * @returns ModalTimeState      时间选择状态
 * @returns Options             多选框数据
 * @returns Options             多选框数据
 *
 *
 * @param FUNC
 * @returns getModalTree        模型选择回调
 * @returns TreeSelect          树形组件选择事件
 * @returns SelectColor         多选框选择处理事件
 * @returns onChangeCheck       多选框选择事件
 * @returns onChangeCheckAll    多选框全选事件
 * @returns ReverseSelection    多选框反选事件
 * @returns TreeSelect          树形组件选择事件
 * @returns TreeSelect          树形组件选择事件
 *
 *
 * @param Tips
 * @returns SelectReminder
 * @returns CommonSuccessMessage
 * @returns CommonErrorMessage
 *
 *
 */

export const ForgeProgress = ({ Off, BIMPlanUuid, organizationUuid, type }) => {
    const ForgeBox = useRef(null)
    const [Viewing, setViewing] = useState()
    // TODO runAsync
    const { runAsync: getBIMDetails } = useRequest(Http, { manual: true })
    const { runAsync: OptionalModalId } = useRequest(Http, { manual: true })
    const { runAsync: OptionalModalTree } = useRequest(Http, { manual: true })
    const { runAsync: posBIMDetails } = useRequest(Http, { manual: true })
    const { runAsync: delBimDetails } = useRequest(Http, { manual: true })

    const { runAsync: getFiles } = useRequest(Http, {
        manual: true,
        onSuccess: res => {
            setFilesList(res.list)
        },
    })

    // TODO 变量
    const [FilesStatus, { setTrue: FilesStatusTrue, setFalse: FilesStatusFalse }] = useBoolean(false)
    const [FilesList, setFilesList] = useState([])
    const [FilesUrl, setFilesUrl] = useState()
    const [TreeData, setTreeData] = useState([])
    const [CheckName, setCheckName] = useState()
    const [PlainOptions, setPlainOptions] = useState([])
    const [CheckStatus, { setTrue: CheckTrue, setFalse: CheckFalse }] = useBoolean(false)
    const [Options, setOptions] = useState([])
    const [CheckSelect, setCheckSelect] = useState([])
    const [CheckAll, setCheckAll] = useState(false)
    const [CheckAllIn, setCheckAllIn] = useState(false)
    const [ModalTime, setModalTime] = useState([])
    const [ModalActiveData, setModalActiveData] = useState([])
    const [ModalListLoading, { setTrue: ModalListLoadingTrue, setFalse: ModalListLoadingFalse }] = useBoolean(false)
    const [ModalTimeState, { setTrue: ModalTimeTrue, setFalse: ModalTimeFalse }] = useBoolean(true)

    // TODO LATEST
    const CheckStatusLatest = useLatest(CheckStatus)
    const CheckSelectLatest = useLatest(CheckSelect)

    // TODO FUNC
    const getModalTree = e => {
        setFilesUrl(e)
        getBIMDetails({ url: 'getBIMPlanDetails', data: { filesUuid: e, BIMPlanUuid } }).then(res => {
            Viewing.start(imageUrl + FilesList.find(v => v.bimFilesUuid === e).url, {}, () => {
                message.success('模型加载成功!')
                Viewing.addEventListener('selection', ({ dbIdArray }) => {
                    if (dbIdArray.length !== 0) {
                        if (CheckStatusLatest.current) {
                            if (CheckSelectLatest.current.findIndex(v => v === dbIdArray[0]) === -1) {
                                let list = [...CheckSelectLatest.current, ...dbIdArray]
                                onChangeCheck(list)
                            } else {
                                let list = CheckSelectLatest.current.filter(num => num !== dbIdArray[0])
                                onChangeCheck(list)
                            }
                        }
                    }
                })
                switch (type) {
                    case 'planAdd':
                        OptionalModalTree({
                            url: 'getGetBIMConstructionTree',
                            data: { filesUuid: e, BIMPlanUuid },
                        }).then(res => {
                            FilesStatusTrue()
                            setTreeData(res)
                        })
                        break
                    case 'planDel':
                        OptionalModalId({ url: 'getGetBIMPlanModlesInfoExternalId', data: { BIMPlanUuid } }).then(
                            res => {
                                let checkData = []
                                let ModalActiveData = {}
                                res.list.forEach(item => {
                                    checkData = [...checkData, item.dbId]
                                    ModalActiveData = { ...ModalActiveData, [item.uuid]: item }
                                    Viewing.setThemingColor(item.dbId, ModalSelectColor)
                                })
                                setModalActiveData(ModalActiveData)
                                OptionalModalTree({
                                    url: 'getGetBIMPlanConstructionTree',
                                    data: { filesUuid: e, BIMPlanUuid },
                                }).then(res => {
                                    FilesStatusTrue()
                                    setTreeData(res)
                                })
                            },
                        )
                        break
                    default:
                        FilesStatusTrue()
                        ModalTimeFalse()
                        break
                }
            })
        })
    }
    const TreeSelect = (_, { node }) => {
        const { tableName, key, children } = node
        if (!children || children.length === 0) {
            let data = {
                ConstructionTreeUuid: key,
                BIMPlanUuid,
            }
            if (ModalTime.length === 2) {
                const [BeginFinishTime, EndFinishTime] = ModalTime
                data.BeginFinishTime = BeginFinishTime
                data.EndFinishTime = EndFinishTime
            }

            OptionalModalId({ url: ApiUrlList[type], data }).then(res => {
                if (res.list.length !== 0) {
                    let data = []
                    let all = []
                    res.list.forEach(item => {
                        data = [...data, { label: item.tableName, value: item.dbId, ...item }]
                        all = [...all, item.dbId]
                    })
                    Viewing.isolate(all)
                    setCheckName(tableName)
                    setOptions(data)
                    setPlainOptions(all)
                    CheckTrue()
                } else {
                    message.info('该节点暂无可选构建')
                    CheckFalse()
                }
            })
        }
    }
    const SelectColor = list => {
        Viewing.clearThemingColors()
        list.forEach(item => Viewing.setThemingColor(item, ModalSelectColor))
    }
    const onChangeCheck = list => {
        SelectColor(list)
        setCheckSelect(list)
        setCheckAllIn(!!list.length && list.length < PlainOptions.length)
        setCheckAll(list.length === PlainOptions.length)
    }
    const onChangeCheckAll = ({ target }) => {
        SelectColor(target.checked ? PlainOptions : [])
        setCheckSelect(target.checked ? PlainOptions : [])
        setCheckAll(target.checked)
        setCheckAllIn(false)
    }
    const ReverseSelection = () => onChangeCheck(GetNewArr(PlainOptions, CheckSelect))

    const ModalDateTime = (_, e) => {
        console.log(e)
        setModalTime(e)
        OptionalModalId({
            url: 'getGetBIMFinishModlesInfoExternalId',
            data: {
                BeginFinishTime: e[0],
                EndFinishTime: e[1],
            },
        }).then(({ list }) => {
            let ModalActiveData = {}
            list.forEach(item => {
                ModalActiveData = { ...ModalActiveData, [item.uuid]: item }
                Viewing.setThemingColor(item.dbId, ModalSelectColor)
            })
            setModalActiveData(ModalActiveData)
            Viewing.clearThemingColors()
            Viewing.showAll()
            list.forEach(item => Viewing.setThemingColor(item.dbId, ModalSelectColor))
        })

        OptionalModalTree({
            url: 'getGetBIMFinishConstructionTreeByFilesUuid',
            data: {
                filesUuid: FilesUrl,
                BeginFinishTime: e[0],
                EndFinishTime: e[1],
            },
        }).then(res => {
            setTreeData(res)
        })
    }

    const ModalDateTimeAdd = (_, e) => {
        setModalTime(e)
        OptionalModalTree({
            url: 'getGetBIMConstructionTreeByFilesUuid',
            data: { filesUuid: FilesUrl },
        }).then(res => {
            FilesStatusTrue()
            setTreeData(res)
        })
    }

    // TODO 初始化页面
    useEffect(() => {
        const viewing = new Autodesk.Viewing.GuiViewer3D(ForgeBox.current)
        Autodesk.Viewing.Initializer({ env: 'Local' }, () => {
            getFiles({ url: 'getBimFileOrganizationRelation', data: { pageIndex: 1, pageSize: 10000 } })
            setViewing(viewing)
            message.info('初始化完成')
        })
    }, [getFiles])

    // 保存
    const ClickSave = () => {
        ModalListLoadingTrue()
        switch (type) {
            case 'planAdd':
                let data = []
                CheckSelect.forEach(
                    item =>
                        (data = [
                            ...data,
                            {
                                modlesInfoUuid: Options.find(v => v.dbId === item).externalId,
                                organizationUuid,
                                BIMPlanUuid,
                            },
                        ]),
                )
                if (data.length === 0) return SelectReminder()

                posBIMDetails({ url: 'posBIMPlanDetails', data })
                    .then(() => CommonSuccessMessage('计划进度添加成功!'))
                    .catch(() => CommonErrorMessage())

                break

            case 'planDel':
                let delData = []
                CheckSelect.forEach(item => (delData = [...delData, Options.find(v => v.dbId === item).uuid]))
                if (delData.length === 0) return SelectReminder()
                delBimDetails({ url: 'posRemoveBIMPlanDetails', data: delData })
                    .then(() => {
                        delData.forEach(item => delete ModalActiveData[item])
                        setModalActiveData(ModalActiveData)
                        CommonSuccessMessage('计划进度删除成功!')
                        message.success('计划进度删除成功!')
                        ModalListLoadingFalse()
                        ClickCancel()
                        CheckFalse()
                    })
                    .catch(() => CommonErrorMessage())

                break
            case 'finishAdd':
                let finishAdd = []
                CheckSelect.forEach(
                    item =>
                        (finishAdd = [
                            ...finishAdd,
                            {
                                modlesInfoUuid: Options.find(v => v.dbId === item).externalId,
                                organizationUuid: JSON.parse(sessionStorage.getItem('UserInfo')).userUuid,
                                finishTime: ModalTime,
                            },
                        ]),
                )
                if (finishAdd.length === 0) return SelectReminder()
                posBIMDetails({ url: 'posBIMFinishDetails', data: finishAdd })
                    .then(() => CommonSuccessMessage('实际进度添加成功!'))
                    .catch(() => CommonErrorMessage())
                break
            case 'finishDel':
                let finishDel = []
                CheckSelect.forEach(item => (finishDel = [...finishDel, Options.find(v => v.dbId === item).uuid]))
                if (finishDel.length === 0) return SelectReminder()
                delBimDetails({ url: 'posRemoveBIMFinishDetails', data: finishDel })
                    .then(() => {
                        ModalDateTime('', ModalTime)
                        CommonSuccessMessage('实际进度删除成功!')
                    })
                    .catch(() => CommonErrorMessage())
                break
            default:
                break
        }
    }

    // 取消
    const ClickCancel = () => {
        Viewing.clearThemingColors()
        Viewing.showAll()
        setCheckAll(false)
        setCheckAllIn(false)
        setCheckSelect([])
        setOptions([])
        setPlainOptions([])
        CheckFalse()
        setCheckName()
        if (ModalActiveData && ModalActiveData.length !== 0)
            Object.values(ModalActiveData).forEach(({ dbId }) => Viewing.setThemingColor(dbId, ModalSelectColor))
    }

    // TODO Tips

    const SelectReminder = () => {
        message.info('请选择构建选择')
        ModalListLoadingFalse()
        return false
    }
    const CommonSuccessMessage = text => {
        message.success(text)
        ModalListLoadingFalse()
        ClickCancel()
        CheckFalse()
    }
    const CommonErrorMessage = () => {
        message.error('接口请求失败!')
        ModalListLoadingFalse()
        ClickCancel()
    }

    return (
        <div className="ForgePlanBox" style={{ height: type === 'finishDel' ? 'calc(100vh - 256px)' : '70vh' }}>
            <div className="ForgeData">
                <Select
                    value={FilesUrl}
                    placeholder="请先选择模型"
                    fieldNames={{ label: 'bim_FilesName', value: 'bimFilesUuid' }}
                    options={FilesList}
                    onChange={e => getModalTree(e)}
                    disabled={FilesStatus}
                />
                {type === 'finishAdd' && (
                    <DatePicker
                        className="finishDelTime"
                        disabled={ModalTimeState}
                        onChange={ModalDateTimeAdd}
                        disabledDate={e => e && e > dayjs().endOf('day')}
                    />
                )}
                {type === 'finishDel' && (
                    <RangePicker
                        className="finishDelTime"
                        disabled={ModalTimeState}
                        onChange={ModalDateTime}
                        disabledDate={e => e && e > dayjs().endOf('day')}
                    />
                )}
                <div className="ForgeTree">
                    {FilesUrl ? (
                        <Tree
                            className="TreeBox"
                            showLine
                            defaultExpandAll
                            treeData={TreeData}
                            fieldNames={{ title: 'tableName', key: 'uuid' }}
                            onSelect={TreeSelect}
                        />
                    ) : (
                        <div className="TreeLoading">
                            <Result title="请先选择模型" />
                        </div>
                    )}
                </div>
            </div>
            <div className="ForgeModalBox" ref={ForgeBox}>
                {CheckStatus && (
                    <Draggable bounds=".ForgeModalBox" handle=".handler">
                        <div>
                            <div className="handler">{CheckName}</div>
                            <div className="dataBox">
                                <Spin spinning={ModalListLoading}>
                                    <div className="all">
                                        <Checkbox
                                            indeterminate={CheckAllIn}
                                            checked={CheckAll}
                                            onChange={onChangeCheckAll}
                                        >
                                            全选
                                        </Checkbox>
                                        <Button type="link" onClick={ReverseSelection}>
                                            反选
                                        </Button>
                                    </div>
                                    <div className="check">
                                        <div className="box" style={{ height: Options.length * 22 }}>
                                            <Group options={Options} value={CheckSelect} onChange={onChangeCheck} />
                                        </div>
                                    </div>
                                    <div className="submit">
                                        <Button type="link" onClick={ClickSave}>
                                            {ButtonText[type]}
                                        </Button>
                                        <Button type="link" onClick={ClickCancel} danger>
                                            关闭
                                        </Button>
                                    </div>
                                </Spin>
                            </div>
                        </div>
                    </Draggable>
                )}
            </div>
        </div>
    )
}
